package com.bcmusic.order.service.impl;
import com.bcmusic.music.feign.MusicFeign;
import com.bcmusic.music.feign.MusicPermissionFeign;
import com.bcmusic.music.pojo.Music;
import com.bcmusic.music.pojo.MusicPermission;
import com.bcmusic.order.dao.OrderCartMapper;
import com.bcmusic.order.domain.cart.dto.AddToCartDTO;
import com.bcmusic.order.domain.cart.vo.OrderCartVO;
import com.bcmusic.order.pojo.OrderCart;
import com.bcmusic.order.service.OrderCartService;
import entity.DateUtil;
import entity.SmartBeanUtil;
import io.swagger.models.auth.In;
import org.aspectj.weaver.ast.Or;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.test.annotation.Rollback;

import java.math.BigDecimal;
import java.util.*;


/****
 * @Author:admin
 * @Description:OrderCart业务层接口实现类
 * @Date 2019/6/14 0:16
 *****/
@Service
public class OrderCartServiceImpl implements OrderCartService {

    @Autowired
    private OrderCartMapper orderCartMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private MusicPermissionFeign musicPermissionFeign;

    @Autowired
    private MusicFeign musicFeign;


    /**
     * 添加订单，重新校验价格以及各种类型合法性,由于购物车经常crud，就不放到数据库啦，直接上redis，更加快捷。
     * 如果将一个商品重复添加购物车的话，就删除
     * @param orderCart
     */
    @Override
    public void add(OrderCart orderCart){
//        if(redisTemplate.boundHashOps(orderCart.getUserNumber()).hasKey(orderCart.getMusicNumber()))
//        {
//            redisTemplate.boundHashOps(orderCart.getUserNumber()).delete(orderCart.getMusicNumber());
//        }
//        redisTemplate.boundHashOps(orderCart.getUserNumber()).put(orderCart.getMusicNumber(),orderCart);
    }

    /**
     * 从购物车删除一个商品
     * @param permissionId
     * @param userNum
     * @return
     */
    @Override
    public Boolean deleteOneCart(Integer permissionId, String userNum)
    {
        //删除之后检查一下
        redisTemplate.boundHashOps("orderCart"+userNum).delete(permissionId);
        //持久化保存
        redisTemplate.persist(userNum);
        return !redisTemplate.boundHashOps("orderCart"+userNum).hasKey(permissionId);
    }

    /**
     * 清空购物车，直接将整个哈希删除
     * @param userNum
     * @return
     */
    @Override
    public Boolean deleteAllCart(String userNum) {
        redisTemplate.delete("orderCart"+userNum);
        return !redisTemplate.hasKey("orderCart"+userNum);
    }

    /**
     * 查询购物车
     * @param userNum
     * @return
     */
    @Override
    public Map<String,Object> findList(String userNum) {
        Map<String,Object>map=new HashMap<>();
        List<OrderCart> values = redisTemplate.boundHashOps("orderCart"+userNum).values();

        assert values != null;
        if(values.size()==0){
            map.put("list",values);
            map.put("status",new ArrayList<>());
            return map;
        }

        //根据音乐id查询作者等
        List<Integer>musicIdList=new ArrayList<>();
        for (int i = 0; i < values.size(); i++) {
            musicIdList.add(values.get(i).getMusicId());
        }
        List<Music> data = musicFeign.getMusicByIdList(musicIdList).getData();
        List<OrderCartVO> orderCartVOS = SmartBeanUtil.copyList(values, OrderCartVO.class);
        for (int i = 0; i < orderCartVOS.size(); i++) {
            orderCartVOS.get(i).setMusicName(data.get(i).getMusicName());
            orderCartVOS.get(i).setComposer(data.get(i).getComposer());
            orderCartVOS.get(i).setSinger(data.get(i).getSinger());
            orderCartVOS.get(i).setLyricist(data.get(i).getLyricist());
            orderCartVOS.get(i).setUserNumber(userNum);
        }

        List<Integer> check = check(values, userNum);
        map.put("list",orderCartVOS);
        map.put("status",check);
        return map;
    }
//
//    /**
//     * 返回选中购物车数据，创建订单：这里有一个大坑！！！由于购物车数据放在redis，假如发布信息过期了，版权方重新发布，由于我这里没有
//     * 去检查购物车中每条数据的合法性（太耗费性能）,这里到时候会有一个bug，计划第二版通过lua脚本同步redis与数据库来解决这个坑，第一版就。。。
//     * 没办法木的事件流我只能diy。。
//     * @param musicNums
//     * @param userNum
//     * @return
//     */
//    @Override
//    @Rollback
//    public List<OrderCart> getCart(List<String> musicNums,String userNum) {
//
//        List<OrderCart> orderCartList = redisTemplate.boundHashOps(userNum).multiGet(musicNums);
//        //如果失败第一个是空
//        orderCartList.remove(null);
//        if(orderCartList.isEmpty())
//        {
//            return null;
//        }
//        //这个地方由于批量插入返回不了主键，我也不知道为啥实在搞不定，就暂时先一个个插入
////        orderCartMapper.insertList(orderCartList);
//        for (int i = 0; i < orderCartList.size(); i++) {
//            orderCartMapper.insertSelective(orderCartList.get(i));
//        }
////        Long delete = redisTemplate.boundHashOps(userNum).delete(musicNums);
//        //这里批量删除不知道为啥无效
//        for (int i = 0; i < musicNums.size(); i++) {
//            redisTemplate.boundHashOps(userNum).delete(musicNums.get(i));
//        }
//        return orderCartList;
//    }

    /**
     * 检查购物车数据合法性,返回一个状态数组
     * @param cartList
     * @return
     */

    @Rollback
    private List<Integer> check(List<OrderCart> cartList,String userNum) {
        List<Integer>idList=new ArrayList<>();
        for (int i = 0; i < cartList.size(); i++) {
            idList.add(cartList.get(i).getPermissionId());
        }
        List<MusicPermission>list= musicPermissionFeign.getPermissionByIdList(idList).getData();
        //返回给前端的状态数组

        //长度不相等代表另一个模块出bug，此时清空购物车免得翻车
        if(list.size()!=idList.size()){
            //清空全部
            redisTemplate.delete("orderCart"+userNum);
            ArrayList<Integer>status=new ArrayList();
            for (int i=0;i<cartList.size();i++){
                status.add(0);
            }
            return status;
        }

        List<Integer>statusList=new ArrayList<>();
        //要在redis删除的
        List<Integer>needDeleteList=new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            if(list.get(i)==null||!list.get(i).getValidStatus().equals(1))
            {
                statusList.add(0);
                needDeleteList.add(cartList.get(i).getPermissionId());
            }else {
                statusList.add(1);
            }
        }
        //我日，上个版本也是这个坑，批量无效
//        redisTemplate.boundHashOps("orderCart"+userNum).delete(needDeleteList);

        for (int i = 0; i < needDeleteList.size(); i++) {
            Long delete = redisTemplate.boundHashOps("orderCart" + userNum).delete(needDeleteList.get(i));
            System.out.println(delete);
        }

        return statusList;
    }


    /**
     * 根据id列表查询购物车  未测试
     * @param idList
     * @return
     */
    @Override
    public List<OrderCart>getCartListByIdList(List<Integer>idList){
        List<OrderCart> carts = orderCartMapper.selectByIdList(idList);
        return carts;
    }

    /**
     * 添加购物车
     * @param addToCartDTO
     * @param userNum
     * @return
     */
    @Override
    public int addToCart(AddToCartDTO addToCartDTO, String userNum) {
        MusicPermission permission = musicPermissionFeign.getPermissionById(addToCartDTO.getPermissionId()).getData();
        if(permission==null||permission.getValidStatus()!=1){
            return 0;
        }
        //授权地域不符合
        if(!addToCartDTO.getAllowRegion().equals(permission.getAllowRegion())&&permission.getAllowRegion()!=2){
            return 2;
        }
        //授权时间不符合
        if(!DateUtil.isContain(permission.getAllowStartTime(), permission.getAllowEndTime(), addToCartDTO.getAuthorizationStartTime(), addToCartDTO.getAuthorizationEndTime())){
            return 3;
        }
        Stack<String>allowType=toStack(permission.getAllowType());
        for (int i = 0; i < addToCartDTO.getAllowType().length; i++) {
            if(!allowType.contains(addToCartDTO.getAllowType()[i])){
                return 4;
            }
        }
        BigDecimal bigDecimal=new BigDecimal(DateUtil.differentDaysByMillisecond(addToCartDTO.getAuthorizationStartTime(), addToCartDTO.getAuthorizationEndTime()));
        BigDecimal pricePerDay=new BigDecimal(permission.getPricePerDay());
        BigDecimal total = bigDecimal.multiply(pricePerDay);
        if(permission.getIsPerpetual()==1){
            if(total.compareTo(new BigDecimal(permission.getPerpetualPrice()))==1)
            {
                total=new BigDecimal(permission.getPerpetualPrice());
            }
        }
        addToCartDTO.setTotalPrices(total.toString());
        OrderCart orderCart = SmartBeanUtil.copy(addToCartDTO, OrderCart.class);
        //
        orderCart.setMusicId(permission.getMusicId());
        orderCart.setAllowType(Arrays.toString(addToCartDTO.getAllowType()));
        //如果购物车有了相同的商品就把之前的删了。。。。虽然这样怪怪的
        if(redisTemplate.boundHashOps("orderCart"+userNum).get(addToCartDTO.getPermissionId().toString())!=null){
            redisTemplate.boundHashOps("orderCart"+userNum).delete(addToCartDTO.getPermissionId().toString());
        }
        redisTemplate.boundHashOps("orderCart"+userNum).put(orderCart.getPermissionId(),orderCart);
        return 1;
    }



    @Override
    public List<OrderCart> getOrderCartListByOrderId(Integer orderId) {
        List<OrderCart> cartListByOrderId = orderCartMapper.findCartListByOrderId(orderId);
        return cartListByOrderId;
    }

    public Stack<String> toStack(String s){
        if(s==null){
            return null;
        }
        StringBuilder stringBuilder=new StringBuilder(s);
        stringBuilder.delete(0,1);
        stringBuilder.delete(stringBuilder.length()-1,stringBuilder.length());
        String []s1=stringBuilder.toString().split(",");


        if(s1.length==0||s1[0].equals("")){
            return null;
        }
        Stack<String> stack=new Stack<>();
        for (int i = 0; i < s1.length; i++) {
            stack.add(s1[i]);
        }
        return stack;
    }

}
